<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>在运动中延长动画</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #container {
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 160px;
            height: 40px;
            border-radius: 40px;
            display: block;
            overflow: hidden;
            /* background-color: palevioletred; */
        }
        span {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background: #4df5c4;
            display: inline-block;
            position: absolute; 
            transform: translateX(0px);
        }
        span:nth-child(1) {
            left: -60px;
        }
        span:nth-child(2) {
            left: 0px;
        }
        span:nth-child(3) {
            left: 60px;
        }
        span:nth-child(4) {
            left: 120px;
        }
    </style>
</head>
<body>
  <!-- https://css-tricks.com/repeatable-staggered-animation-three-ways-sass-gsap-web-animations-api/ -->
    <div id="container">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
    <script>
      const iterationTaggerAni = (els, options = { totalTime: 1, aniTime: 0.3, taggerTime: 0.2 }) => {
        const { totalTime, aniTime, taggerTime } = options;
        [...els].forEach((el, i) => {
          // 创建4个关键帧
          const frames = [
            { transform: `translateX(0)`, offset: 0 },
            { transform: `translateX(0)`, offset: Math.min((i * taggerTime) / totalTime, 1) },
            { transform: `translateX(60px)`, offset: Math.min((i * taggerTime + aniTime) / totalTime, 1) },
            { transform: `translateX(60px)`, offset: 1 },
          ]
          el = els[els.length - 1 - i];
          el.animate(frames, {
            fill: 'none', // 运动结束后，恢复默认状态
            iterations: Infinity, // 不断重复
            duration: totalTime * 1000, // n秒
            easing: "ease-in-out"
          });
        })
      }
      iterationTaggerAni(document.querySelectorAll('span'), {
        totalTime: 0.6,
        aniTime: 0.3,
        taggerTime: 0.1 // 每个都延迟0.1秒。但是第一个索引是0, 0*0.1 = 0，所以，第一个实际上延迟0s
      });
      // taggerTime * maxIndex + aniTime == totalTime, 没有大于总时间
      // 0.1 * 3 + 0.3 === 0.6
    </script>
</body>
</html>